package com.huangsm.book.designmodel.key;


import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author huang
 * @date 2019/2/20
 */
public class ThreadLocalDemo implements Runnable{
    private static final ThreadLocal<Date>localvar=new ThreadLocal<>();
    private long time;

    public ThreadLocalDemo(long time) {
        this.time = time;
    }

    @Override
    public void run() {
        Date date=new Date(time);
        for (int i = 0; i < 50000; i++) {
            localvar.set(date);
            if (localvar.get().getTime()!=time){
                System.out.println("id="+time+"localvar"+localvar.get().getTime());
            }
        }
    }

    public static void main(String[] args) {
        ThreadPoolExecutor executor=new ThreadPoolExecutor(100,100,0L, TimeUnit.SECONDS,new LinkedBlockingQueue<>());
        long time = System.currentTimeMillis();
        ThreadLocalDemo threadLocalDemo=new ThreadLocalDemo(time);
        //executor.execute(threadLocalDemo);
        threadLocalDemo.run();
    }
}
/**
 * 説明:
 * 如果使用不同的时间构造以上线程，在并发时，可以保证多个线程间的localvar变量是独立的。虽然没有同步操作
 * 但是多个线程间的数据不会互相影响。因此，永远不可能出现当前线程持有时间和成员变量time不同的情况。
 * 通过ThreadLocal的set方法可以看出
 *    public void set(T value) {
 *         Thread t = Thread.currentThread(); //首先获取当前线程
 *         ThreadLocalMap map = getMap(t);//现根据线程对象获取ThreadLocalMap
 *         if (map != null) //如果不为空，这将值存入ThreadLocalMap
 *             map.set(this, value);
 *         else
 *             createMap(t, value);//否则创建新的ThreadLocalMap并且将线程对象和值放入
 *     }
 * 这样做保证了线程的安全性，如果同一个实例设置到不同线程的ThreadLocal中，线程安全无法保证
 */
